from pynput import keyboard
import queue
import time
import threading
import asyncio, asyncvnc
from enum import Enum

'''
202412-29 14:59 当前这条技术路线行不通，看来得键盘监听线程实时维护按键set
'''
async def VNCconsumer():
    holdingKeySet = set() # 一个数组，记录了当前按下的所有按键 
    async with asyncvnc.connect('localhost') as client:
        while True:
            # 按下按键
            with client.keyboard.hold(*holdingKeySet):
                # 等待获取新按键（这个get方法会阻塞线程）
                newKeyBean:KeyBean = keyQueue.get(True)
                print('comsume {} time{}'.format(newKeyBean.key, time.ctime(time.time())))
                print(holdingKeySet)
                # 向 holdingKeySet 中添加或删除按键
                if(newKeyBean.holdOrRelease == KEY_OPEAR.PRESS):
                    holdingKeySet.add(newKeyBean.key)
                else:
                    holdingKeySet.remove(newKeyBean.key)
                # 离开with代码块，此时所有按键被VNC释放，然后重新从循环头部进入时，按键会被client.keyboard.hold方法再次按下

class KEY_OPEAR(Enum):
    PRESS = 1 # 按住按键
    RELEASE = 2 # 释放按键

class KeyBean:
    def __init__(self, key: str, holdOrRelease: KEY_OPEAR):
        self.key = key
        self.holdOrRelease = holdOrRelease

# keyboard的消费者线程
class ConsumerThread(threading.Thread):
    def __init__(self, name, queue):
        super().__init__()
        self.name = name
        self.queue = queue

    def run(self):
        print('Thread: {} start at {}'.format(self.name, time.ctime(time.time())))

        # 启动VNC协程（这个协程内部会阻塞线程。这个写法很屎，但我不熟悉协程，python多线程，keyboard库，asyncVNC这些代码，所以暂时想不出更好的）
        asyncio.run(VNCconsumer())

def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(key.char))
        # 将按下的按键塞进队列中
        keyQueue.put(KeyBean(key.char, KEY_OPEAR.PRESS))
    except AttributeError:
        print('special key {0} pressed'.format(key))

def on_release(key):
    print('{0} released'.format(key))
    # 将释放的按键塞进队列中
    keyQueue.put(KeyBean(key.char, KEY_OPEAR.PRESS))
    # if key == keyboard.Key.esc:
    #     # Stop listener
    #     return False


keyQueue = queue.Queue()

threads = []
[threads.append(ConsumerThread(str(i), keyQueue)) for i in range(1,2)]

# 启动所有线程
[t.start() for t in threads]


# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

